//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Malla.h"

//---------------------------------------------------------------------------
Malla::Malla(){
}

Malla::Malla(int nV,PV3D** vertices,int nN,PV3D** normales,int nC,Cara** caras){
}

Malla::~Malla(){
        int i;
        for(i=0;i<_nVertice;i++){
                delete _vertice[i];
        }
        for(i=0;i<_nNormal;i++){
                delete _normal[i];
        }
        for(i=0;i<_nCara;i++){
                delete _cara[i];
        }
        delete[] _vertice;
        delete[] _normal;
        delete[] _cara;
}

void Malla::dibuja(bool relleno){
        for(int i=0; i<_nCara; i++){
                if(relleno){
                        glBegin(GL_POLYGON);
                }else{
                        glBegin(GL_LINE_LOOP);
                }
                for(int j=0; j<_cara[i]->getNumVertices(); j++){
                        int iN=_cara[i]->getIN(j);
                        int iV=_cara[i]->getIV(j);
                        glNormal3d(_normal[iN]->getX(),_normal[iN]->getY(),
                                _normal[iN]->getZ());            
                        glVertex3d(_vertice[iV]->getX(),_vertice[iV]->getY(),
                                _vertice[iV]->getZ());
                }
                glEnd();
        }
}

void Malla::pintaNormales(){
        double x,y,z,xf,yf,zf;
        for(int i=0; i<_nNormal;i++){
                glBegin(GL_LINES);
                        x=_vertice[i]->getX();
                        y=_vertice[i]->getY();
                        z=_vertice[i]->getZ();
                        glVertex3d(x,y,z);
                        xf=x+_normal[i]->getX();
                        yf=y+_normal[i]->getY();
                        zf=z+_normal[i]->getZ();
                        glVertex3d(xf,yf,zf);
                glEnd();
        }
}

PV3D* Malla::newell(PV3D** vertices, PV3D**& normales, VerticeNormal** parejas,int n){
        double nx,ny,nz,xi,yi,zi,xsuc,ysuc,zsuc;
        PV3D* normalc,*nodo;
        nx=ny=nz=0;
        for (int i=0; i<n; i++){
                xi=vertices[parejas[i]->getVertice()]->getX();
                yi=vertices[parejas[i]->getVertice()]->getY();
                zi=vertices[parejas[i]->getVertice()]->getZ();

                if(i+1<n-1){
                        xsuc=vertices[parejas[i+1]->getVertice()]->getX();
                        ysuc=vertices[parejas[i+1]->getVertice()]->getY();
                        zsuc=vertices[parejas[i+1]->getVertice()]->getZ();
                }else{
                        xsuc=vertices[parejas[(i+1)%n]->getVertice()]->getX();
                        ysuc=vertices[parejas[(i+1)%n]->getVertice()]->getY();
                        zsuc=vertices[parejas[(i+1)%n]->getVertice()]->getZ();
                }
                nx+=(yi-ysuc)*(zi+zsuc);
                ny+=(zi-zsuc)*(xi+xsuc);
                nz+=(xi-xsuc)*(yi+ysuc);
        }
        normalc=new PV3D(nx,ny,nz,0);
        normalc->normaliza();
        normalc->opuesto();

        for(int i=0; i<n; i++){
                normales[parejas[i]->getNormal()]->mueve(normalc->getX(),
                        normalc->getY(),normalc->getZ());
        }
        return normalc;
}

PV3D* Malla::matrizPorPunto(double** matriz, PV3D* punto){
        PV3D* resultado;
        double x,y,z;
        x=(punto->getX()*matriz[0][0])+(punto->getY()*matriz[0][1])
                +(punto->getZ()*matriz[0][2])+ matriz[0][3];
        y=(punto->getX()*matriz[1][0])+(punto->getY()*matriz[1][1])
                +(punto->getZ()*matriz[1][2])+matriz[1][3];
        z=(punto->getX()*matriz[2][0])+(punto->getY()*matriz[2][1])
                +(punto->getZ()*matriz[2][2])+matriz[2][3];

        resultado=new PV3D(x,y,z,1);

        return resultado;
}
//---------------------------------------------------------------------------
#pragma package(smart_init)
